package irc

import (
	"io"
	"ircove.com/common"
)

type IMessage interface {
	Encode(w io.Writer) error
	Decode(r io.Reader) error
}
type Message struct {
	Header *Header
	Data   []byte
}

func (this *Message)SetData(bytes []byte)  {
       this.Header.SetMessageLen(len(bytes))
       this.Data=bytes
}

func (this *Message)Clone(bytes []byte) (message *Message, err error) {

	 return NewMessage(this.Header.MessageType,this.Header.MessageFormat,int(this.Header.MessageID),bytes)
}

func NewMessage(messageType MessageType, messageFormat uint8, messageid int, data []byte) (message *Message, err error) {
	header := new(Header)
	message = &Message{
		Header: header,
		Data:   data,
	}
	if messageType> messagetype_max || messageType<1{
		return message, common.ErrorArgument
	}
	header.MessageType = messageType
	header.MessageFormat = messageFormat
	err = header.SetMessageID(messageid)
	if err != nil {
		return message, err
	}
	err = header.SetMessageLen(len(data))
	if err != nil {
		return message, err
	}
	return message, nil
}

func (this *Message) Decode(r io.Reader) error {
	head := &Header{}
	err := head.Decode(r)
	if err != nil {
		 return err
	}
	this.Header = head
	if !head.HasMessageLen {
		return nil
	}
	var buf []byte = make([]byte, head.MessageLen, head.MessageLen)

	if _, err := r.Read(buf); err != nil {
		return common.NetWorkError
	}
	this.Data = buf
	return nil
}
func (this *Message) Encode(w io.Writer) error {
	if this.Header == nil {
		return common.ErrorArgument.Clone("message header not empty")
	}
	len := len(this.Data)
	if len!= int(this.Header.MessageLen){
		return common.ErrorArgument.Clone("this *Message Encode this.Header.MessageLen ! len(this.Data)")
	}
	//if len > 0 && int(this.Header.MessageLen) != len {
	//	this.Header.SetMessageLen(len)
	//}
	if err := this.Header.Encode(w); err != nil {
		return err
	}
	_, err := w.Write(this.Data[:])
	if err != nil {
		return common.NetWorkError.Clone(err.Error())
	}
	return nil
}
